home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Framework / Sources / UScripting.cp < prev    next >
Encoding:
Text File  |  1996-04-03  |  62.0 KB  |  1,948 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UScripting.cp
  3. // Copyright © 1988-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __USCRIPTING__
  7. #include "UScripting.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. #ifndef __UCOMMANDHANDLER__
  13. #include "UCommandHandler.h"
  14. #endif
  15.  
  16. #ifndef __UCOREERRORMGR__
  17. #include "UCoreErrorMgr.h"
  18. #endif
  19.  
  20. #ifndef __UCOREGLOBALS__
  21. #include "UCoreGlobals.h"
  22. #endif
  23.  
  24. #ifndef __UCOREUTILITIES__
  25. #include "UCoreUtilities.h"
  26. #endif
  27.  
  28. //    #ifndef __UDIALOG__
  29. //    #include "UDialog.h"
  30. //    #endif
  31.  
  32. #ifndef __UDISPATCHER__
  33. #include "UDispatcher.h"
  34. #endif
  35.  
  36. //    #ifndef __UERRORMGR__
  37. //    #include "UErrorMgr.h"
  38. //    #endif
  39.  
  40. #ifndef __ULISTITERATOR__
  41. #include "UListIterator.h"
  42. #endif
  43.  
  44. #ifndef __UMACAPPGLOBALS__
  45. #include "UMacAppGlobals.h"
  46. #endif
  47.  
  48. #ifndef __UMACAPPUTILITIES__
  49. #include "UMacAppUtilities.h"
  50. #endif
  51.  
  52. #ifndef __UMEMORY__
  53. #include "UMemory.h"
  54. #endif
  55.  
  56. #ifndef __USUBSTITUTION__
  57. #include "USubstitution.h"
  58. #endif
  59.  
  60. // Toolbox
  61.  
  62. #ifndef __AEPACKOBJECT__
  63. #include <AEPackObject.h>
  64. #endif
  65.  
  66. #ifndef __AEREGISTRY__
  67. #include <AERegistry.h>
  68. #endif
  69.  
  70. #ifndef __MENUS__
  71. #include <Menus.h>
  72. #endif
  73.  
  74. #ifndef __RESOURCES__
  75. #include <Resources.h>
  76. #endif
  77.  
  78. // ANSI
  79.  
  80. #if qDebugMsg
  81.     #ifndef __STDIO__
  82.     #include <stdio.h>
  83.     #endif
  84. #endif
  85.  
  86. //========================================================================================
  87. // Static data allocations
  88. //========================================================================================
  89.  
  90. TOSADispatcher* TOSADispatcher::fgDispatcher;
  91.  
  92. //==================================================================================================
  93. // class TOSADispatcher
  94. //==================================================================================================
  95. #undef Inherited
  96. #define Inherited TObject
  97.  
  98. #pragma segment ConstructorRes
  99. MA_DEFINE_CLASS_M1(TOSADispatcher, Inherited);
  100.  
  101. //----------------------------------------------------------------------------------------
  102. // TOSADispatcher::InitUScripting
  103. //----------------------------------------------------------------------------------------
  104. #pragma segment MAInit
  105.  
  106. void TOSADispatcher::InitUScripting(MA_ClassReference classDesc)
  107. {
  108.     if (!IsHighLevelEventAware())
  109.     {
  110. #if qDebug
  111.         DebugStr((StringPtr)"\p###Not HighLevelEventAware! Check SIZE resource.");
  112. #endif
  113.         ExitToShell();
  114.     }
  115.  
  116.     if (TOSADispatcher::fgDispatcher)
  117.     {
  118. #if qDebugMsg
  119.         fprintf(stderr, "Scripting already initialized\n");
  120. #endif
  121.     }
  122.     else
  123.     {
  124.         AEObjectInit();
  125.         qd.randSeed = TickCount();
  126.         
  127.         if (!classDesc)
  128.         {
  129. #if qDebug
  130.             DebugStr((StringPtr)"\pNULL classDesc for scripting dispatcher");
  131. #endif
  132.             Failure(minErr, 0);
  133.         }
  134.         
  135.         fgDispatcher = (TOSADispatcher*) classDesc->Call_DefaultConstructor();
  136.         fgDispatcher->IOSADispatcher();
  137.         
  138.         InitUSubstitution();
  139.     }
  140. }
  141.  
  142. //----------------------------------------------------------------------------------------
  143. // TOSADispatcher::TOSADispatcher : 
  144. //----------------------------------------------------------------------------------------
  145. #pragma segment MAApplicationRes
  146.  
  147. TOSADispatcher::TOSADispatcher()
  148.     : fDefaultTarget(NULL),
  149.       fTemporaryTokens(NULL),
  150.       fPendingReplyList(NULL),
  151.       fDispatchUPP(NULL),
  152. #if qAttachable
  153.       fAttachedScripts(0),
  154.       fPreDispatchUPP(NULL),
  155. #endif
  156.       fAccessorUPP(NULL),
  157.       fCompareUPP(NULL),
  158.       fCountUPP(NULL),
  159.       fDisposeTokenUPP(NULL),
  160.       fGetMarkTokenUPP(NULL),
  161.       fMarkUPP(NULL),
  162.       fAdjustMarksUPP(NULL),
  163.       fDispatchLevel(0),
  164.       fAEResolveFlags(kAEIDoMinimum | kAEIDoWhose | kAEIDoMarking)
  165. {
  166.     
  167. }
  168.  
  169. //----------------------------------------------------------------------------------------
  170. // TOSADispatcher::~TOSADispatcher : 
  171. //----------------------------------------------------------------------------------------
  172. #pragma segment MAApplicationRes
  173.  
  174. TOSADispatcher::~TOSADispatcher()
  175. {
  176.     // dispose the routine descriptors allocated by this object
  177.     
  178.     // ••• Should remove handlers first!!!
  179.     
  180. #if qAttachable
  181.     fPreDispatchUPP = DisposeIfRoutineDescriptor(fPreDispatchUPP);
  182. #endif
  183.     TAppleEvent::fgIdleProc = DisposeIfRoutineDescriptor(TAppleEvent::fgIdleProc);
  184.     fDispatchUPP = DisposeIfRoutineDescriptor(fDispatchUPP);
  185.     fAccessorUPP = DisposeIfRoutineDescriptor(fAccessorUPP);
  186.     fCompareUPP = DisposeIfRoutineDescriptor(fCompareUPP);
  187.     fCountUPP = DisposeIfRoutineDescriptor(fCountUPP);
  188.     fDisposeTokenUPP = DisposeIfRoutineDescriptor(fDisposeTokenUPP);
  189.     fGetMarkTokenUPP = DisposeIfRoutineDescriptor(fGetMarkTokenUPP);
  190.     fMarkUPP = DisposeIfRoutineDescriptor(fMarkUPP);
  191.     fAdjustMarksUPP = DisposeIfRoutineDescriptor(fAdjustMarksUPP);
  192.     
  193.     fTemporaryTokens = (TList *)FreeIfObject(fTemporaryTokens);
  194.     fPendingReplyList = (TEventList *)FreeIfObject(fPendingReplyList);
  195. }
  196.  
  197. //----------------------------------------------------------------------------------------
  198. // TOSADispatcher::IOSADispatcher : 
  199. //----------------------------------------------------------------------------------------
  200. #pragma segment MAOSLDispatch
  201.  
  202. void TOSADispatcher::IOSADispatcher()
  203. {
  204.     this->IObject();
  205.         
  206.     fTemporaryTokens = NewList();
  207.     fPendingReplyList = new TEventList;
  208.     fPendingReplyList->IEventList();
  209.  
  210. #if qDebug
  211.     fPendingReplyList->SetEltType("TClientCommand");
  212. #endif
  213.     
  214.     this->InstallDispatchHandlers();
  215.     this->InstallObjectCallbacks();
  216. }
  217.  
  218. //----------------------------------------------------------------------------------------
  219. // TOSADispatcher::InstallDispatchHandlers : 
  220. //----------------------------------------------------------------------------------------
  221. #pragma segment MAInit
  222. // Just in case, this should be in a different segment than the glue it installs
  223.  
  224. void TOSADispatcher::InstallDispatchHandlers()
  225. {
  226.     MAVolatileInit(Handle, tableHandle, NULL);
  227.     MAVolatile(SignedByte, savedState);
  228.     
  229.     if (!TAppleEvent::fgIdleProc)
  230.     {
  231.         TAppleEvent::fgIdleProc = NewAEIdleProc(MacAppAppleEventIdleProc);
  232.         FailNIL(TAppleEvent::fgIdleProc);
  233.     }
  234.  
  235.     if (!fDispatchUPP)
  236.     {
  237.         fDispatchUPP = NewAEEventHandlerProc(TOSADispatcher::DispatchHandlerGlue);
  238.         FailNIL(fDispatchUPP);
  239.     }
  240.  
  241.     short numberOfTables = MACount1Resources('aedt'); // count the number of table resources
  242.     FailResError();
  243.     
  244.     FailInfo fi;
  245.     Try(fi)
  246.     {
  247.         for (short tableIndex = 1; tableIndex <= numberOfTables; ++tableIndex)
  248.         {
  249.             tableHandle = MAGet1IndResource('aedt', tableIndex);
  250.             FailNILResource(tableHandle);
  251.             savedState = LockHandle(tableHandle);
  252.             Size tableSize = GetHandleSize(tableHandle);
  253.             FailMemError();
  254.             short tableElements = (short)(tableSize / sizeof(MAEventTableRec));
  255.                 
  256.             MAEventTableRec *tablePtr = (MAEventTableRec*)*tableHandle;
  257.                 
  258.             for (short eventIndex = 1; eventIndex <= tableElements; ++eventIndex)
  259.             {
  260.                 // install the same event handler for all events
  261.                 FailOSErr(AEInstallEventHandler(tablePtr->theClass, tablePtr->theID,
  262.                              fDispatchUPP, tablePtr->theValue, FALSE));
  263.                 tablePtr++;
  264.             }
  265.                 
  266.             HSetState(tableHandle, savedState);
  267.             ReleaseResource(tableHandle);
  268.             tableHandle = NULL;
  269.         }
  270.         fi.Success();
  271.     }
  272.     else    // Recover
  273.     {
  274.         if (tableHandle)
  275.         {
  276.             HSetState(tableHandle, savedState);
  277.             ReleaseResource(tableHandle);
  278.         }
  279.         fi.ReSignal();
  280.     }
  281. }
  282.  
  283. #if qAttachable
  284.  
  285. //----------------------------------------------------------------------------------------
  286. // TOSADispatcher::ScriptAttached : 
  287. //----------------------------------------------------------------------------------------
  288. #pragma segment MAOSLDispatch
  289.  
  290. void TOSADispatcher::ScriptAttached()
  291. {
  292.     if (++fAttachedScripts == 1)
  293.         InstallPreDispatchHandler();
  294. }
  295.  
  296. //----------------------------------------------------------------------------------------
  297. // TOSADispatcher::ScriptDetached : 
  298. //----------------------------------------------------------------------------------------
  299. #pragma segment MAOSLDispatch
  300.  
  301. void TOSADispatcher::ScriptDetached()
  302. {
  303. #if qDebug
  304.     Assertion(fAttachedScripts >= 0, "\pToo many calls to ScriptDetached");
  305. #endif
  306.     if (--fAttachedScripts == 0)
  307.         RemovePreDispatchHandler();
  308. }
  309.  
  310. //----------------------------------------------------------------------------------------
  311. // TOSADispatcher::InstallPreDispatchHandler : 
  312. //----------------------------------------------------------------------------------------
  313. #pragma segment MAOSLDispatch
  314. // Just in case, this should be in a different segment than the glue it installs
  315.  
  316. void TOSADispatcher::InstallPreDispatchHandler()
  317. {
  318.     if (HasAppleScript())
  319.     {    
  320.         if  (!fPreDispatchUPP)
  321.         {
  322.             fPreDispatchUPP = NewAEEventHandlerProc(TOSADispatcher::PreDispatchHandlerGlue);
  323.             FailNIL(fPreDispatchUPP);
  324.         }
  325.         FailOSErr(AEInstallSpecialHandler(keyPreDispatch, (UniversalProcPtr)fPreDispatchUPP, FALSE));
  326.     }
  327. }
  328.  
  329. //----------------------------------------------------------------------------------------
  330. // TOSADispatcher::RemovePreDispatchHandler : 
  331. //----------------------------------------------------------------------------------------
  332. #pragma segment MAOSLDispatch
  333.  
  334. void TOSADispatcher::RemovePreDispatchHandler()
  335. {
  336.     if (HasAppleScript() && (fPreDispatchUPP != NULL))
  337.         FailOSErr(AERemoveSpecialHandler(keyPreDispatch, (UniversalProcPtr)fPreDispatchUPP, FALSE));
  338. }
  339.  
  340. #endif // qAttachable
  341.  
  342. //----------------------------------------------------------------------------------------
  343. // TOSADispatcher::InstallObjectCallbacks : 
  344. //----------------------------------------------------------------------------------------
  345. #pragma segment MAOSLDispatch
  346. // Just in case, this should be in a different segment than the glue it installs
  347.  
  348. void TOSADispatcher::InstallObjectCallbacks()
  349. {
  350.         // install the universal object accessor
  351.     fAccessorUPP = NewOSLAccessorProc(TOSADispatcher::ObjectAccessorGlue);
  352.     FailOSErr(AEInstallObjectAccessor(typeWildCard, typeWildCard, fAccessorUPP, 0, FALSE));
  353.     
  354.     fCompareUPP = NewOSLCompareProc(TOSADispatcher::CompareObjectsGlue);
  355.     fCountUPP = NewOSLCountProc(TOSADispatcher::CountObjectsGlue);
  356.     fDisposeTokenUPP = NewOSLDisposeTokenProc(TOSADispatcher::DisposeTokenGlue);
  357.     fGetMarkTokenUPP = NewOSLGetMarkTokenProc(TOSADispatcher::GetMarkTokenGlue);
  358.     fMarkUPP = NewOSLMarkProc(TOSADispatcher::MarkObjectGlue);
  359.     fAdjustMarksUPP = NewOSLAdjustMarksProc(TOSADispatcher::AdjustMarksGlue);
  360.     
  361.     FailOSErr(AESetObjectCallbacks(fCompareUPP, fCountUPP, fDisposeTokenUPP,
  362.                                    fGetMarkTokenUPP, fMarkUPP, fAdjustMarksUPP, NULL));
  363. }
  364.  
  365. #if qAttachable
  366.  
  367. //----------------------------------------------------------------------------------------
  368. // TOSADispatcher::PreDispatchHandler : 
  369. //----------------------------------------------------------------------------------------
  370. #pragma segment MAOSLDispatch
  371.  
  372. OSErr TOSADispatcher::PreDispatchHandler(CommandNumber    aCommandNumber,
  373.                                         TAppleEvent*     message,
  374.                                          TAppleEvent*    reply)
  375. {
  376.     MScriptableObject     *targetObject;
  377.     MAVolatileInit(OSErr, err, noErr);
  378.         
  379.     FailInfo fi;
  380.     Try(fi)
  381.     {
  382.         targetObject = this->GetTargetObject(aCommandNumber, message);
  383.         err = targetObject->HandleOSAEvent(aCommandNumber, message, reply) ? noErr : errAEEventNotHandled;
  384.         fi.Success();
  385.     }
  386.     else    // recover
  387.     {
  388.         // if the event is an "exists" event and the target was not found
  389.         // return false instead of an error
  390.  
  391.         if (aCommandNumber == cAEDoObjectsExist && fi.error == errAENoSuchObject)
  392.             ((TAppleEvent *)reply)->WriteBoolean(keyAEResult, FALSE);
  393.         else
  394.             fi.ReSignal();
  395.     }
  396.         
  397.     return err;
  398. }
  399.  
  400. #endif // qAttachable
  401.  
  402. //----------------------------------------------------------------------------------------
  403. // TOSADispatcher::DispatchHandler : 
  404. //----------------------------------------------------------------------------------------
  405. #pragma segment MAOSLDispatch
  406.  
  407. OSErr TOSADispatcher::DispatchHandler(    CommandNumber    aCommandNumber,
  408.                                         TAppleEvent*     message,
  409.                                          TAppleEvent*    reply)
  410. {
  411.     MAVolatileInit(OSErr, err, noErr);
  412.     
  413.     FailInfo fi;
  414.     Try(fi)
  415.     {
  416.         MScriptableObject         *targetObject;
  417.         TScriptableObjectList     *theObjectList;
  418.         Boolean                    targetIsContainer = FALSE;
  419.  
  420.         targetObject = this->GetTargetObject(aCommandNumber, message);
  421.     
  422.         if (targetObject->GetOMClass() == cScriptableObjectList)
  423.         {
  424.             FailNonObject(theObjectList = MA_DYNAMIC_CAST(TScriptableObjectList, targetObject));
  425.             targetObject = theObjectList->GetObjectsContainer();
  426.             targetIsContainer = TRUE;
  427.         }
  428.         
  429. #if qOptimizeSelfSendAevt        
  430.         long transactionID = message->GetTransactionID();
  431.         if (targetObject->IsPendingAction(aCommandNumber, transactionID))
  432.             err = errAEEventNotHandled;
  433.         else
  434. #endif
  435.         {
  436.             // print events directed at objects other than the application
  437.             // need to be handled as cPrint commands. 
  438.             if (aCommandNumber == cFinderPrint && targetObject != gDispatcher)
  439.                 aCommandNumber = cPrint;
  440.                 
  441.             if (targetIsContainer)
  442.                 targetObject->DoAEOnContainedObjects(theObjectList, aCommandNumber, message, reply);
  443.             else
  444.                 targetObject->HandleScriptCommand(aCommandNumber, message, reply);
  445.         }
  446.         fi.Success();
  447.     }
  448.     else    // recover
  449.     {    
  450.         // if the event is an "exists" event and the target was not found
  451.         // return false instead of an error
  452.  
  453.         if (aCommandNumber == cAEDoObjectsExist && fi.error == errAENoSuchObject)
  454.             ((TAppleEvent *)reply)->WriteBoolean(keyAEResult, FALSE);
  455.         else
  456.             fi.ReSignal();
  457.     }
  458.     
  459.     return err;
  460. } // TOSADispatcher::DispatchHandler
  461.  
  462. //----------------------------------------------------------------------------------------
  463. // TOSADispatcher::ReportDispatchError :
  464. // Note: This function is invoked when an error occurs during processing of an incoming
  465. // AppleEvent. All calls to subroutines must call resident code. Apple event manager
  466. // calls are made directly, rather than through TAppleEvent, to eliminate dependencies
  467. // on non-resident code.
  468. //----------------------------------------------------------------------------------------
  469. #pragma segment MAScriptingRes
  470.  
  471. void TOSADispatcher::ReportDispatchError(AppleEvent*     messageEvent,
  472.                                          AppleEvent*     replyEvent,
  473.                                          OSErr            dispatchErr,
  474.                                          long            dispatchErrMessage)
  475. {
  476.     Boolean sentToSelf = FALSE;
  477.     Boolean interactWithUser = FALSE;
  478.     Boolean senderWantsReply = FALSE;
  479.     OSErr    err;
  480.     
  481.     if (messageEvent)
  482.     {
  483.         ProcessSerialNumber eventPSN;
  484.         DescType            actualType;
  485.         Size                actualSize;
  486.         AESendMode            sendMode;
  487.         
  488.         err = AEGetAttributePtr(messageEvent, keyAddressAttr, typeProcessSerialNumber,
  489.             &actualType, &eventPSN, sizeof(ProcessSerialNumber), &actualSize);
  490.         if (err == noErr)
  491.             SameProcess(&eventPSN, &gDispatcher->fProcessNumber, &sentToSelf);
  492.         
  493.         err = AEGetAttributePtr(messageEvent, keyInteractLevelAttr, typeShortInteger,
  494.             &actualType, &sendMode, sizeof(short), &actualSize);
  495.         if (err == noErr)
  496.             senderWantsReply = (sendMode & kAEReplyModeMask) != kAENoReply;
  497.     }
  498.     
  499.     if (!sentToSelf && !senderWantsReply)
  500.     {
  501.         // pass NULL for the idling proc. incoming events right now might
  502.         // cause memory problems
  503.         interactWithUser = MAInteractWithUserNoIdleProc() == noErr;
  504.     }
  505.             
  506.     // Put up a dialog if:
  507.     //   1) we are not responding to an event sent by ourself AND
  508.     //   2) the client doesn't expect a reply AND
  509.     //   3) user interaction is acceptable.
  510.     
  511.     if (!sentToSelf && !senderWantsReply && interactWithUser)
  512.         gDispatcher->ShowError(dispatchErr, dispatchErrMessage);
  513.     
  514.     if (replyEvent && (replyEvent->descriptorType != typeNull) && (replyEvent->dataHandle != NULL))
  515.     {
  516.         long     failureError = dispatchErr;    // needs to be a signed long
  517.         CStr255    errStr;
  518.         AEPutParamPtr(replyEvent, keyErrorNumber, typeLongInteger, &failureError, sizeof(long));
  519.         if (!LookupErrString(dispatchErr, errReasonID, errStr))
  520.         {
  521.             // No error string was found, substitute the generic one.
  522.             CStr255 errNumStr;
  523.             LookupErrString(errGenericErrorWithNum, errReasonID, errStr);
  524.             NumToString(dispatchErr, errNumStr);
  525.             MAParamText("^ENUM", errNumStr);
  526.             MAReplaceText(errStr);
  527.         }
  528.         AEPutParamPtr(replyEvent, keyErrorString, typeChar, &errStr[1], errStr.Length());
  529.     }
  530. } // TOSADispatcher::ReportDispatchError
  531.  
  532. //----------------------------------------------------------------------------------------
  533. // TOSADispatcher::GetTargetObject : 
  534. //----------------------------------------------------------------------------------------
  535. #pragma segment MAOSLDispatch
  536.  
  537. MScriptableObject* TOSADispatcher::GetTargetObject(    CommandNumber aCommandNumber,
  538.                                                     TAppleEvent* appleEvent)
  539. {
  540.     CTempDesc            objectDesc;
  541.     OSErr                err = noErr;
  542.     MScriptableObject     *targetObject = NULL;
  543.     
  544.     // Get the direct object of the event. If the event is a create element event,
  545.     // use the insertion object.
  546.     if (aCommandNumber == cAECreateElement)
  547.         FailOSErr(appleEvent->ReadParameter(keyAEInsertHere, typeWildCard, objectDesc));
  548.     else
  549.         err = appleEvent->ReadParameter(keyDirectObject, typeWildCard, objectDesc);
  550.     
  551.     if (err == errAEDescNotFound)
  552.         targetObject = this->GetDefaultTarget();
  553.     else
  554.     {
  555.         FailOSErr(err);
  556.         if (objectDesc.GetDescriptorType() == typeInsertionLoc)
  557.         {
  558.             CTempDesc insertionDesc;
  559.  
  560.             FailOSErr(AECoerceDesc(objectDesc, typeAERecord, insertionDesc));
  561.             FailOSErr(objectDesc.DisposeDesc());
  562.             insertionDesc.GetKeyDesc(keyAEObject, typeWildCard, objectDesc);
  563.             appleEvent->WriteParameter(keyDirectObject, objectDesc);
  564.         }
  565.  
  566.         targetObject = this->ResolveObjectSpecifier(objectDesc);
  567.     }
  568.     return targetObject;
  569. }
  570.  
  571. //----------------------------------------------------------------------------------------
  572. // TOSADispatcher::ResolveObjectSpecifier : Ask the OSL to resolve an object specifier. 
  573. // This will initiate a dialog between the OSL and our object resolution callbacks. 
  574. //----------------------------------------------------------------------------------------
  575. #pragma segment MAOSLDispatch
  576.  
  577. MScriptableObject* TOSADispatcher::ResolveObjectSpecifier(CAEDesc&     objectDesc)
  578. {
  579.     MScriptableObject     *result;
  580.             
  581.     if (objectDesc.GetDescriptorType() == typeObjectSpecifier)
  582.     {
  583.         CTempDesc             tokenDesc;
  584.         
  585.         FailOSErr(AEResolve(objectDesc, fAEResolveFlags, tokenDesc));
  586.         result = tokenDesc.GetObject();
  587.     }
  588.     else
  589.         result = this->GetDefaultTarget();
  590.     
  591.     return result;
  592. }
  593.  
  594. //----------------------------------------------------------------------------------------
  595. // GetAppleEventCommandNumber: return the commandNumber associated with a specific
  596. // event class and ID.
  597. //----------------------------------------------------------------------------------------
  598. #pragma segment MAOSLDispatch
  599.  
  600. CommandNumber TOSADispatcher::GetAppleEventCommandNumber(AEEventClass     eventClass,
  601.                                                         AEEventID         eventID)
  602. {
  603.     AEEventClass        localClass = eventClass;
  604.     AEEventID            localID = eventID;
  605.     OSErr                err;
  606.     long                theCommandNumber = 0;
  607.     AEEventHandlerUPP    eventHandler = NULL;
  608.     
  609.     err = AEGetEventHandler(eventClass, eventID, &eventHandler, &theCommandNumber, FALSE);
  610.     if (err != noErr)
  611.         theCommandNumber = 0;
  612.         
  613.     return theCommandNumber;
  614. }
  615.  
  616.  
  617. //----------------------------------------------------------------------------------------
  618. // TOSADispatcher::ObjectAccessor : Handles the AccessContainedObjects OSL callback by
  619. // asking the container object to return a reference to a specific contained object. If
  620. // the object was created for object resolution, and requires disposal later, it is added
  621. // to the temp tokens list.
  622. //----------------------------------------------------------------------------------------
  623. #pragma segment MAOSLDispatch
  624.  
  625. void TOSADispatcher::ObjectAccessor(DescType     desiredClass,
  626.                                     CAEDesc&     container,
  627.                                     DescType    /* containerClass */,
  628.                                     DescType     form,
  629.                                     CAEDesc&     selectionData,
  630.                                     CAEDesc&     value,
  631.                                     long        /* accessorRefcon */)
  632. {
  633.     MScriptableObject *containerObject = container.GetObject();
  634.     if (containerObject == NULL)
  635.         containerObject = fDefaultTarget;
  636.         
  637.     MScriptableObject *resultObject = NULL;
  638.     resultObject = containerObject->GetContainedObject(desiredClass, form, selectionData);
  639.     if (resultObject == NULL)
  640.         FailOSErr(errAENoSuchObject);
  641.     
  642.     value.PutObject(resultObject);
  643. }
  644.  
  645. //----------------------------------------------------------------------------------------
  646. // TOSADispatcher::CountObjects: Handle the OSL CountObjects callback by asking
  647. // a container object to count the contained objects of a certain type.
  648. //----------------------------------------------------------------------------------------
  649. #pragma segment MAOSLDispatch
  650.  
  651. long TOSADispatcher::CountObjects(    DescType     desiredType,
  652.                                     DescType     /*containerClass*/,
  653.                                        CAEDesc&     container)
  654. {
  655.     MScriptableObject *theContainer = container.GetObject();
  656.     return theContainer->CountContainedObjects(desiredType);
  657.  
  658. //----------------------------------------------------------------------------------------
  659. // TOSADispatcher::CompareObjects: Handle the OSL CompareObjects callback by asking
  660. // the target object to compare itself to another object.
  661. //----------------------------------------------------------------------------------------
  662. #pragma segment MAOSLDispatch
  663.  
  664. Boolean TOSADispatcher::CompareObjects(    DescType     whichOperation,
  665.                                         CAEDesc&     targetDesc,
  666.                                         CAEDesc&     thingToCompare)
  667. {
  668.     MScriptableObject *theTargetObject = targetDesc.GetObject();
  669.     return theTargetObject->CompareScriptableObjects(whichOperation, thingToCompare);
  670. }
  671.  
  672. //----------------------------------------------------------------------------------------
  673. // TOSADispatcher::DisposeToken: The OSL calls this method after object resolution but
  674. // before the event is processed. After an event is processed, all temporary tokens
  675. // are disposed.
  676. //----------------------------------------------------------------------------------------
  677. #pragma segment MAOSLDispatch
  678.  
  679. void TOSADispatcher::DisposeToken(CAEDesc& unneededToken)
  680. {
  681.     FailOSErr(unneededToken.DisposeDesc());
  682. }
  683.  
  684. //----------------------------------------------------------------------------------------
  685. // TOSADispatcher::GetMarkToken: Before marking a set of objects, the OSL asks for a
  686. // token to contain them.  MacApp provides a TScriptableObjectList.
  687. //----------------------------------------------------------------------------------------
  688. #pragma segment MAOSLDispatch
  689.  
  690. void TOSADispatcher::GetMarkToken( CAEDesc& theContainerToken,
  691.                                    DescType    /*containerClass*/,
  692.                                    CAEDesc& result)
  693. {
  694.     MScriptableObject *containerObject = theContainerToken.GetObject();
  695.     TScriptableObjectList *theMarkingList = containerObject->MakeNewMarkingList();
  696.     FailNonObject(theMarkingList);
  697.     result.PutObject(theMarkingList);
  698. }
  699.  
  700. //----------------------------------------------------------------------------------------
  701. // TOSADispatcher::MarkObject: OSL is requesting the specified object be marked.
  702. //----------------------------------------------------------------------------------------
  703. #pragma segment MAOSLDispatch
  704.  
  705. void TOSADispatcher::MarkObject(CAEDesc& theToken,
  706.                                 CAEDesc& markingListToken,
  707.                                 long    /*index*/)
  708. {
  709.     MScriptableObject *markingListObject = markingListToken.GetObject();
  710.     TScriptableObjectList *theMarkingList = MA_DYNAMIC_CAST(TScriptableObjectList, markingListObject);
  711.     FailNonObject(theMarkingList);
  712.     MScriptableObject *objectToMark = theToken.GetObject();
  713.     theMarkingList->InsertMarkedObject(objectToMark);
  714. }
  715.  
  716. //----------------------------------------------------------------------------------------
  717. // TOSADispatcher::AdjustMarks: 
  718. //----------------------------------------------------------------------------------------
  719. #pragma segment MAOSLDispatch
  720.  
  721. void TOSADispatcher::AdjustMarks(long         newStart,
  722.                                  long         newStop,
  723.                                  CAEDesc&     markToken)
  724. {
  725.     // Ask the TAppleObjectList marking list to adjust the items it contains.
  726.     MScriptableObject *markObject = markToken.GetObject();
  727.     TScriptableObjectList *theMarkingList = MA_DYNAMIC_CAST(TScriptableObjectList, markObject);
  728.     FailNonObject(theMarkingList);
  729.     theMarkingList->AdjustMarks(newStart, newStop);
  730. }
  731.  
  732. //----------------------------------------------------------------------------------------
  733. // TOSADispatcher::PostPendingReplyCommand: 
  734. //----------------------------------------------------------------------------------------
  735. #pragma segment MAOSLDispatch
  736.  
  737. void TOSADispatcher::PostPendingReplyCommand(TCommand* command)
  738. {
  739.     fPendingReplyList->Insert(command);
  740. }
  741.  
  742.  
  743. //----------------------------------------------------------------------------------------
  744. // TOSADispatcher::MatchReplyToPending: 
  745. //----------------------------------------------------------------------------------------
  746. #pragma segment MAOSLDispatch
  747.  
  748. void TOSADispatcher::MatchReplyToPending(TAppleEvent* reply)
  749. {
  750.     TClientCommand * theMatchedCommand = NULL;
  751.  
  752.     // Higher priority events are at the end of the list.
  753.     CObjectIterator iter(fPendingReplyList, kIterateBackward);
  754.  
  755.     for (TClientCommand * aCommand = (TClientCommand *)iter.FirstObject(); iter.More(); aCommand = (TClientCommand *)iter.NextObject())
  756.     {
  757.         if (aCommand->GetReturnID() == reply->GetReturnID())
  758.         {
  759.             theMatchedCommand = aCommand;
  760.             break;
  761.         }
  762.     }
  763.  
  764.     if (theMatchedCommand)
  765.     {
  766.         fPendingReplyList->Delete(theMatchedCommand);
  767.         theMatchedCommand->ProcessReply(reply);
  768.         theMatchedCommand->fContext->PostCommand(theMatchedCommand);
  769.     }
  770.     else
  771.         FailOSErr(errAEEventNotHandled);
  772. }
  773.  
  774. //----------------------------------------------------------------------------------------
  775. // TOSADispatcher::GetTemporaryTokens
  776. //----------------------------------------------------------------------------------------
  777. #pragma segment MAOSLDispatch
  778.  
  779. TList* TOSADispatcher::GetTemporaryTokens()
  780. {
  781.     return fTemporaryTokens;
  782. }
  783.  
  784. //----------------------------------------------------------------------------------------
  785. // TOSADispatcher::AddTemporaryToken: Insert an object into the temp tokens list.
  786. // Temp tokens will be discarded after the target is resolved and the event is executed.
  787. //----------------------------------------------------------------------------------------
  788. #pragma segment MAOSLDispatch
  789.  
  790. void TOSADispatcher::AddTemporaryToken(TObject* tempToken)
  791. {
  792.     if (fTemporaryTokens->GetEqualItemNo(tempToken) == kEmptyIndex)
  793.         fTemporaryTokens->InsertLast(tempToken);
  794. }
  795.  
  796. //----------------------------------------------------------------------------------------
  797. // TOSADispatcher::FreeTemporaryTokens: 
  798. //----------------------------------------------------------------------------------------
  799. #pragma segment MAOSLDispatch
  800.  
  801. void TOSADispatcher::FreeTemporaryTokens()
  802. {
  803.     // Frees all the objects in the temp token list.
  804.     if (fTemporaryTokens && (fDispatchLevel < 1))
  805.     {
  806.         FailInfo fi;    // swallow errors
  807.         Try(fi)
  808.         {
  809.             fTemporaryTokens->FreeAll();
  810.             fi.Success();
  811.         }
  812.     }
  813. }
  814.  
  815. #if qAttachable
  816.  
  817. //----------------------------------------------------------------------------------------
  818. // TOSADispatcher::PreDispatchHandlerGlue : AppleScript does not send the refCon
  819. // associated with the standard dispatch handler for the event.
  820. //----------------------------------------------------------------------------------------
  821. #pragma segment MAScriptingRes
  822.  
  823. pascal OSErr TOSADispatcher::PreDispatchHandlerGlue(AppleEvent* message,
  824.                                                     AppleEvent* reply,
  825.                                                     long        /* info */)
  826. {
  827.     MAVolatileInit(TAppleEvent*, messageEvent, NULL);
  828.     MAVolatileInit(TAppleEvent*, replyEvent, NULL);
  829.     OSErr dispatchErr = noErr;
  830.     long dispatchErrMessage = 0L;
  831.     
  832.     TOSADispatcher::fgDispatcher->fDispatchLevel++;
  833.  
  834.     FailInfo fi;
  835.     Try(fi)
  836.     {
  837.         AEEventClass    eventClass;
  838.         AEEventID        eventID;
  839.         CommandNumber    eventCommand = 0;
  840.  
  841.         messageEvent = new TAppleEvent;
  842.         messageEvent->InitializeFromMessage(*message, FALSE);
  843.         replyEvent = new TAppleEvent;
  844.         replyEvent->InitializeFromMessage(*reply, FALSE);
  845.         
  846.         eventClass = messageEvent->ReadEventClass();
  847.         eventID = messageEvent->ReadEventID();
  848.         eventCommand = TOSADispatcher::fgDispatcher->GetAppleEventCommandNumber(eventClass, eventID);
  849.     
  850.         dispatchErr = TOSADispatcher::fgDispatcher->PreDispatchHandler(eventCommand, messageEvent, replyEvent);
  851.         fi.Success();
  852.     }
  853.     else
  854.     {
  855.         dispatchErr = fi.error;                // Don't propogate the error.
  856.         dispatchErrMessage = fi.message;    
  857.     }
  858.     
  859.     if (dispatchErr != noErr && dispatchErr != errAEEventNotHandled)
  860.         TOSADispatcher::fgDispatcher->ReportDispatchError(message, reply, dispatchErr, dispatchErrMessage);
  861.         
  862.     TOSADispatcher::fgDispatcher->fDispatchLevel--;
  863.     TOSADispatcher::fgDispatcher->FreeTemporaryTokens();
  864.  
  865.     FreeIfObject(messageEvent);
  866.     FreeIfObject(replyEvent);
  867.     
  868.     return dispatchErr;
  869. } // TOSADispatcher::PreDispatchHandlerGlue
  870.  
  871. #endif // qAttachable
  872.  
  873. //----------------------------------------------------------------------------------------
  874. // TOSADispatcher::DispatchHandlerGlue
  875. //----------------------------------------------------------------------------------------
  876. #pragma segment MAScriptingRes
  877.  
  878. pascal OSErr TOSADispatcher::DispatchHandlerGlue(AppleEvent*     message,
  879.                                                  AppleEvent*     reply,
  880.                                                  long            info)
  881. {
  882.     MAVolatileInit(TAppleEvent*, messageEvent, NULL);
  883.     MAVolatileInit(TAppleEvent*, replyEvent, NULL);
  884.     OSErr dispatchErr = noErr;
  885.     long dispatchErrMessage = 0L;
  886.     Boolean matchedToPending = FALSE;
  887.     CommandNumber itsCommand = (CommandNumber)info;
  888.     
  889.     TOSADispatcher::fgDispatcher->fDispatchLevel++;
  890.  
  891.     FailInfo fi;
  892.     Try(fi)
  893.     {
  894.         messageEvent = new TAppleEvent;
  895.         messageEvent->InitializeFromMessage(*message, FALSE);
  896.         replyEvent = new TAppleEvent;
  897.         replyEvent->InitializeFromMessage(*reply, FALSE);
  898.         
  899.         if (itsCommand == cAppleEventReply)        // handle incoming replies to client commands
  900.         {
  901.             TOSADispatcher::fgDispatcher->MatchReplyToPending(messageEvent);
  902.             matchedToPending = TRUE;
  903.         }
  904.         else
  905.             dispatchErr = TOSADispatcher::fgDispatcher->DispatchHandler(itsCommand, messageEvent, replyEvent);
  906.         
  907.         fi.Success();
  908.     }
  909.     else // recover
  910.     {
  911.         dispatchErr = fi.error;                // Do not propogate the error.
  912.         dispatchErrMessage = fi.message;    
  913.     }
  914.     
  915.     if (dispatchErr != noErr && dispatchErr != errAEEventNotHandled)
  916.         TOSADispatcher::fgDispatcher->ReportDispatchError(message, reply, dispatchErr, dispatchErrMessage);
  917.  
  918.     TOSADispatcher::fgDispatcher->fDispatchLevel--;
  919.     TOSADispatcher::fgDispatcher->FreeTemporaryTokens();
  920.         
  921.     // delete the message only if it wasn't matched to a pending command
  922.     if (!matchedToPending)
  923.         FreeIfObject(messageEvent);
  924.     FreeIfObject(replyEvent);
  925.     
  926.     return dispatchErr;
  927. } // TOSADispatcher::DispatchHandlerGlue
  928.  
  929. //----------------------------------------------------------------------------------------
  930. // TOSADispatcher::ObjectAccessorGlue
  931. //----------------------------------------------------------------------------------------
  932. #pragma segment MAScriptingRes
  933.  
  934. pascal OSErr TOSADispatcher::ObjectAccessorGlue(DescType     desiredClass, 
  935.                                                 AEDesc*     container, 
  936.                                                 DescType     containerClass, 
  937.                                                 DescType     form, 
  938.                                                 AEDesc*     selectionData, 
  939.                                                 AEDesc*     value,
  940.                                                 long         accessorRefcon)
  941. {
  942.     OSErr result = noErr;
  943.     
  944.     CAEDesc    containerDesc(container);
  945.     CAEDesc    selectionDesc(selectionData);
  946.     CAEDesc    valueDesc(value);
  947.     
  948.     FailInfo fi;
  949.     Try(fi)
  950.     {
  951.         TOSADispatcher::fgDispatcher->ObjectAccessor(desiredClass, containerDesc, containerClass, 
  952.                 form, selectionDesc, valueDesc, accessorRefcon);
  953.         *value = *(AEDesc *)valueDesc;
  954.         fi.Success();
  955.     }
  956.     else
  957.         result = fi.error;
  958.         
  959.     return result;
  960. }
  961.  
  962. //----------------------------------------------------------------------------------------
  963. // TOSADispatcher::CountObjectsGlue
  964. //----------------------------------------------------------------------------------------
  965. #pragma segment MAScriptingRes
  966.  
  967. pascal OSErr TOSADispatcher::CountObjectsGlue(    DescType     desiredType,
  968.                                                 DescType    containerClass,
  969.                                                 AEDesc*        container,
  970.                                                 long*         result)
  971. {
  972.     OSErr err = noErr;
  973.     CAEDesc    containerDesc(container);
  974.     
  975.     FailInfo fi;
  976.     Try(fi)
  977.     {
  978.         *result = TOSADispatcher::fgDispatcher->CountObjects(desiredType, containerClass, containerDesc);
  979.         fi.Success();
  980.     }
  981.     else
  982.         err = fi.error;
  983.         
  984.     return err;
  985. }
  986.  
  987. //----------------------------------------------------------------------------------------
  988. // TOSADispatcher::CompareObjectsGlue
  989. //----------------------------------------------------------------------------------------
  990. #pragma segment MAScriptingRes
  991.  
  992. pascal OSErr TOSADispatcher::CompareObjectsGlue(DescType     whichOperation,
  993.                                                 AEDesc*     obj1,
  994.                                                 AEDesc*     obj2,
  995.                                                 Boolean*     result)
  996. {
  997.     OSErr errResult = noErr;
  998.     CAEDesc    object1Desc(obj1);
  999.     CAEDesc    object2Desc(obj2);
  1000.     
  1001.     FailInfo fi;
  1002.     Try(fi)
  1003.     {
  1004.         *result = TOSADispatcher::fgDispatcher->CompareObjects(whichOperation, object1Desc, object2Desc);
  1005.         fi.Success();
  1006.     }
  1007.     else
  1008.         errResult = fi.error;
  1009.         
  1010.     return errResult;
  1011. }
  1012.  
  1013. //----------------------------------------------------------------------------------------
  1014. // TOSADispatcher::DisposeTokenGlue
  1015. //----------------------------------------------------------------------------------------
  1016. #pragma segment MAScriptingRes
  1017.  
  1018. pascal OSErr TOSADispatcher::DisposeTokenGlue(AEDesc* unneededToken)
  1019. {
  1020.     OSErr     result = noErr;
  1021.     CAEDesc    tokenDesc(unneededToken);
  1022.     
  1023.     FailInfo fi;
  1024.     Try(fi)
  1025.     {
  1026.         TOSADispatcher::fgDispatcher->DisposeToken(tokenDesc);
  1027.         *unneededToken = *(AEDesc *)tokenDesc;
  1028.         fi.Success();
  1029.     }
  1030.     else
  1031.         result = fi.error;
  1032.         
  1033.     return result;
  1034. }
  1035.  
  1036. //----------------------------------------------------------------------------------------
  1037. // TOSADispatcher::GetMarkTokenGlue
  1038. //----------------------------------------------------------------------------------------
  1039. #pragma segment MAScriptingRes
  1040.  
  1041.  pascal OSErr TOSADispatcher::GetMarkTokenGlue(    AEDesc*     containerToken,
  1042.                                                 DescType     containerClass,
  1043.                                                 AEDesc*     result)
  1044. {
  1045.     OSErr theErr = noErr;
  1046.     CAEDesc    containerDesc(containerToken);
  1047.     CAEDesc    markDesc(result);
  1048.     
  1049.     FailInfo fi;
  1050.     Try(fi)
  1051.     {
  1052.         TOSADispatcher::fgDispatcher->GetMarkToken(containerDesc, containerClass, markDesc);
  1053.         *result = *(AEDesc *)markDesc;
  1054.         fi.Success();
  1055.     }
  1056.     else
  1057.         theErr = fi.error;
  1058.         
  1059.     return theErr;
  1060. }
  1061.  
  1062. //----------------------------------------------------------------------------------------
  1063. // TOSADispatcher::MarkObjectGlue
  1064. //----------------------------------------------------------------------------------------
  1065. #pragma segment MAScriptingRes
  1066.  
  1067. pascal OSErr TOSADispatcher::MarkObjectGlue(AEDesc* dToken,
  1068.                                             AEDesc* markToken,
  1069.                                             long     index)
  1070. {
  1071.     OSErr result = noErr;
  1072.     FailInfo fi;
  1073.     Try(fi)
  1074.     {
  1075.         CAEDesc localToken(dToken);
  1076.         CAEDesc localMarkToken(markToken);
  1077.         TOSADispatcher::fgDispatcher->MarkObject(localToken, localMarkToken, index);
  1078.         fi.Success();
  1079.     }
  1080.     else
  1081.         result = fi.error;
  1082.     return result;
  1083. }
  1084.  
  1085. //----------------------------------------------------------------------------------------
  1086. // TOSADispatcher::AdjustMarksGlue
  1087. //----------------------------------------------------------------------------------------
  1088. #pragma segment MAScriptingRes
  1089.  
  1090. pascal OSErr TOSADispatcher::AdjustMarksGlue(long newStart,
  1091.                                              long newStop,
  1092.                                              AEDesc* markToken)
  1093. {
  1094.     OSErr result = noErr;
  1095.     CAEDesc    markDesc(markToken);
  1096.     
  1097.     FailInfo fi;
  1098.     Try(fi)
  1099.     {
  1100.         TOSADispatcher::fgDispatcher->AdjustMarks(newStart, newStop, markDesc);
  1101.         fi.Success();
  1102.     }
  1103.     else
  1104.         result = fi.error;
  1105.     return result;
  1106. }
  1107.  
  1108. //==================================================================================================
  1109. // Class TSetPropertyCommand
  1110. //==================================================================================================
  1111. #undef Inherited
  1112. #define Inherited TCommand
  1113.  
  1114. #pragma segment ConstructorRes
  1115. MA_DEFINE_CLASS_M1(TSetPropertyCommand, Inherited);
  1116.             
  1117. //----------------------------------------------------------------------------------------
  1118. // TSetPropertyCommand::TSetPropertyCommand
  1119. //----------------------------------------------------------------------------------------
  1120.  
  1121. TSetPropertyCommand::TSetPropertyCommand()
  1122.     : fObjectsToSet(NULL),
  1123.       fObjectsToFree(NULL),
  1124.       fProperty('\?\?\?\?'),
  1125.       fOldPropData(),
  1126.       fNewPropData()
  1127. {
  1128. }
  1129.  
  1130. //----------------------------------------------------------------------------------------
  1131. // TSetPropertyCommand::~TSetPropertyCommand
  1132. //----------------------------------------------------------------------------------------
  1133. #pragma segment ASelCommand
  1134.  
  1135. TSetPropertyCommand::~TSetPropertyCommand()
  1136. {
  1137.     fObjectsToSet = (TList *)FreeIfObject(fObjectsToSet);
  1138.     fObjectsToFree = (TList *)FreeListIfObject(fObjectsToFree);
  1139. }
  1140.  
  1141. //----------------------------------------------------------------------------------------
  1142. // TSetPropertyCommand::ISetPropertyCommand
  1143. //----------------------------------------------------------------------------------------
  1144. #pragma segment ASelCommand
  1145.  
  1146. void TSetPropertyCommand::ISetPropertyCommand(DescType theProperty,
  1147.                                               TList* theObjectsToSet,
  1148.                                               TAppleEvent* message,
  1149.                                               TAppleEvent* /* reply */)
  1150. {
  1151.     // We take charge of the temporary objects in the disposal list so we can use them
  1152.     // during execution of this command.
  1153.     // We'll free these when we commit.
  1154.     TList * theDisposalList = TOSADispatcher::fgDispatcher->GetTemporaryTokens();
  1155.     fObjectsToFree = (TList *)theDisposalList->Clone();
  1156.     theDisposalList->DeleteAll();
  1157.     // We'll clone the list so the caller can free it immediately.
  1158.     fObjectsToSet = (TList *)theObjectsToSet->Clone();
  1159.     fProperty = theProperty;
  1160.     CommandNumber cmdNum;
  1161.     Boolean canUndo;
  1162.     Boolean causesChange;
  1163.     TObject * theFirstObject = theObjectsToSet->At(1);
  1164.     FailNIL(theFirstObject);
  1165.  
  1166.     // Get the info for this command from the object.
  1167.     TCommandHandler* itsContext = NULL;
  1168.     ((MScriptableObject*)theFirstObject)->GetSetPropertyInfo(theProperty, cmdNum, canUndo, causesChange, itsContext);
  1169.     this->ICommand(cmdNum, itsContext, canUndo, causesChange, itsContext);
  1170.  
  1171.     fOldPropData = NULL;
  1172.  
  1173.     CAEDesc newPropData;
  1174.     message->ReadParameter(keyAEData, typeWildCard, newPropData);
  1175.     fNewPropData = newPropData;
  1176. }
  1177.  
  1178. //----------------------------------------------------------------------------------------
  1179. // TSetPropertyCommand::DoIt
  1180. //----------------------------------------------------------------------------------------
  1181. #pragma segment ASelCommand
  1182.  
  1183. void TSetPropertyCommand::DoIt()
  1184. {
  1185.     CAEDesc theOldPropList;
  1186.     if (fCanUndo)
  1187.     {
  1188.         theOldPropList.CreateList();
  1189.  
  1190.         CObjectIterator iter(fObjectsToSet);
  1191.         for (TObject * anObject = iter.FirstObject(); iter.More(); anObject = iter.NextObject())
  1192.         {
  1193.             CTempDesc thePropData;
  1194.             ((MScriptableObject*)anObject)->GetObjectProperty(thePropData, fProperty, CAEDesc::fgNullDesc);
  1195.             FailOSErr(AEPutDesc(theOldPropList, 0, thePropData));
  1196.         }
  1197.     }
  1198.     fOldPropData = theOldPropList;
  1199.         
  1200.     this->RedoIt();
  1201. }
  1202.  
  1203. //----------------------------------------------------------------------------------------
  1204. // TSetPropertyCommand::UndoIt
  1205. //----------------------------------------------------------------------------------------
  1206. #pragma segment ASelCommand
  1207.  
  1208. void TSetPropertyCommand::UndoIt()
  1209. {
  1210.     CAEDesc theOldPropData(fOldPropData);
  1211.     Assertion(theOldPropData.GetDataHandle() != NULL, "Trying to undo with no data!");
  1212.     CObjectIterator iter(fObjectsToSet);
  1213.     short listIndex = 1;
  1214.     for (TObject * anObject = iter.FirstObject(); iter.More(); anObject = iter.NextObject())
  1215.     {
  1216.         CTempDesc theOldPropDesc;
  1217.         DescType theActualKey;
  1218.         FailOSErr(AEGetNthDesc(theOldPropData, listIndex++, typeWildCard, &theActualKey, theOldPropDesc));
  1219.         ((MScriptableObject*)anObject)->SetObjectProperty(theOldPropDesc, fProperty);
  1220.     }
  1221. }
  1222.  
  1223. //----------------------------------------------------------------------------------------
  1224. // TSetPropertyCommand::RedoIt
  1225. //----------------------------------------------------------------------------------------
  1226. #pragma segment ASelCommand
  1227.  
  1228. void TSetPropertyCommand::RedoIt()
  1229. {
  1230.     CAEDesc thePropData(fNewPropData);
  1231.     CObjectIterator iter(fObjectsToSet);
  1232.     for (TObject * anObject = iter.FirstObject(); iter.More(); anObject = iter.NextObject())
  1233.         ((MScriptableObject*)anObject)->SetObjectProperty(thePropData, fProperty);
  1234. }
  1235.  
  1236. //----------------------------------------------------------------------------------------
  1237. // TPropertyAccessor
  1238. //----------------------------------------------------------------------------------------
  1239. #undef Inherited
  1240. #define Inherited TObject
  1241.  
  1242. #pragma segment ConstructorRes
  1243. MA_DEFINE_CLASS_M2(TPropertyAccessor, Inherited, MScriptableObject);
  1244.  
  1245. //----------------------------------------------------------------------------------------
  1246. // TPropertyAccessor::TPropertyAccessor
  1247. //----------------------------------------------------------------------------------------
  1248.  
  1249. TPropertyAccessor::TPropertyAccessor()
  1250.     : MScriptableObject(cProperty)
  1251. {
  1252. }                                                // TPropertyAccessor::TPropertyAccessor
  1253.  
  1254. //----------------------------------------------------------------------------------------
  1255. // TPropertyAccessor destructor
  1256. //----------------------------------------------------------------------------------------
  1257. #pragma segment MADestructorRes
  1258.  
  1259. TPropertyAccessor::~TPropertyAccessor()
  1260. {
  1261. }
  1262.  
  1263. //----------------------------------------------------------------------------------------
  1264. // TPropertyAccessor::IPropertyAccessor
  1265. //----------------------------------------------------------------------------------------
  1266. #pragma segment MAOSLDispatch
  1267.  
  1268. void TPropertyAccessor::IPropertyAccessor(MScriptableObject* whichObject,
  1269.                                           DescType whichProperty)
  1270. {
  1271.     // Records which object and property to act on.
  1272.     IObject();
  1273.     fWhichObject = whichObject;
  1274.     fWhichProperty = whichProperty;
  1275. }
  1276.  
  1277. //----------------------------------------------------------------------------------------
  1278. // TPropertyAccessor::GetCommandContext
  1279. //----------------------------------------------------------------------------------------
  1280. #pragma segment MAOSLDispatch
  1281.  
  1282. TCommandHandler* TPropertyAccessor::GetCommandContext(const CommandNumber aCommandNumber) const
  1283. {
  1284.     TCommandHandler *commandHandler = NULL;
  1285.     
  1286.     if (fWhichObject)
  1287.     {    
  1288.         commandHandler = MA_DYNAMIC_CAST(TCommandHandler, fWhichObject);
  1289.         if (commandHandler)
  1290.             commandHandler = commandHandler->GetContext(aCommandNumber);
  1291.     }
  1292.     
  1293.     if (!commandHandler)
  1294.         commandHandler = MScriptableObject::GetCommandContext(aCommandNumber);
  1295.     
  1296.     return commandHandler;
  1297. }
  1298.  
  1299. //----------------------------------------------------------------------------------------
  1300. // TPropertyAccessor::DoScriptCommand
  1301. //----------------------------------------------------------------------------------------
  1302. #pragma segment MAOSLDispatch
  1303.  
  1304. void TPropertyAccessor::DoScriptCommand(CommandNumber     aCommandNumber,
  1305.                                         TAppleEvent*    message,
  1306.                                            TAppleEvent*     reply)
  1307. {
  1308.     // Handles GetData and SetData for this property.
  1309.     FailInfo fi;
  1310.     Try(fi)
  1311.     {
  1312.         switch (aCommandNumber)
  1313.         {
  1314.             case cAEGetData:
  1315.                 {
  1316.                     CTempDesc requestedType;
  1317.                     if (message->HasParameter(keyAERequestedType))
  1318.                         message->ReadParameter(keyAERequestedType, typeWildCard, requestedType);
  1319.                     
  1320.                     CTempDesc thePropertyValue;
  1321.                     fWhichObject->GetObjectProperty(thePropertyValue, fWhichProperty, requestedType);
  1322.                     reply->WriteParameter(keyAEResult, thePropertyValue);
  1323.                     break;
  1324.                 }
  1325.             case cAESetData:
  1326.                 {
  1327.                     TList * aOneObjectList = NewList();
  1328.                     aOneObjectList->InsertLast((TObject*)fWhichObject);
  1329.                     TSetPropertyCommand * theCmd = new TSetPropertyCommand;
  1330.                     theCmd->ISetPropertyCommand(fWhichProperty, aOneObjectList, message, reply);
  1331.                     aOneObjectList = (TList *)FreeIfObject(aOneObjectList);
  1332.                     theCmd->Process();
  1333.                     break;
  1334.                 }
  1335.             default:
  1336.                 MScriptableObject::DoScriptCommand(aCommandNumber, message, reply);
  1337.                 break;
  1338.         }
  1339.         fi.Success();
  1340.     }
  1341.     else
  1342.     {
  1343.         reply->WriteOSError(fi.error);
  1344.     }
  1345. }
  1346.  
  1347. //----------------------------------------------------------------------------------------
  1348. // TPropertyAccessor::CompareScriptableObjects
  1349. //----------------------------------------------------------------------------------------
  1350. #pragma segment MAOSLDispatch
  1351.  
  1352. Boolean TPropertyAccessor::CompareScriptableObjects(DescType operation,
  1353.                                                const CAEDesc& thingToCompare)
  1354. {
  1355.     // Compares the properties.
  1356.     return fWhichObject->CompareProperties(fWhichProperty, operation, thingToCompare);
  1357. }
  1358.  
  1359. //----------------------------------------------------------------------------------------
  1360. // TPropertyAccessor::SetObjectProperty
  1361. //----------------------------------------------------------------------------------------
  1362. #pragma segment MAOSLDispatch
  1363.  
  1364. void TPropertyAccessor::SetObjectProperty(const CAEDesc& thePropertyValue,
  1365.                                            DescType whichProperty)
  1366. {
  1367.     fWhichObject->SetObjectProperty(thePropertyValue, whichProperty);
  1368. }
  1369.  
  1370. //----------------------------------------------------------------------------------------
  1371. // TPropertyAccessor::GetObjectProperty
  1372. //----------------------------------------------------------------------------------------
  1373. #pragma segment MAOSLDispatch
  1374.  
  1375. Boolean TPropertyAccessor::GetObjectProperty(CAEDesc& thePropertyValue,
  1376.                                              DescType whichProperty,
  1377.                                              const CAEDesc& desiredType)
  1378. {
  1379.     return fWhichObject->GetObjectProperty(thePropertyValue, whichProperty, desiredType);
  1380. }
  1381.  
  1382. //----------------------------------------------------------------------------------------
  1383. // TPropertyAccessor::DoAEGetDataSize
  1384. //----------------------------------------------------------------------------------------
  1385. #pragma segment MAOSLDispatch
  1386.  
  1387. void TPropertyAccessor::DoAEGetDataSize(TAppleEvent* message,
  1388.                                         TAppleEvent* reply)
  1389. {
  1390.     CTempDesc requestedType;
  1391.     if (message->HasParameter(keyAERequestedType))
  1392.         message->ReadParameter(keyAERequestedType, typeWildCard, requestedType);
  1393.     
  1394.     CTempDesc thePropertyValue;
  1395.     fWhichObject->GetObjectProperty(thePropertyValue, fWhichProperty, CAEDesc::fgNullDesc);
  1396.     long theSize = thePropertyValue.GetDataSize();
  1397.     reply->WriteLong(keyAEResult, theSize);
  1398. }
  1399.  
  1400. #if qAttachable
  1401.  
  1402. //----------------------------------------------------------------------------------------
  1403. // TPropertyAccessor::HandleOSAEvent:
  1404. //----------------------------------------------------------------------------------------
  1405. #pragma segment MAScriptingRes
  1406.  
  1407. Boolean TPropertyAccessor::HandleOSAEvent(    CommandNumber     aCommandNumber,
  1408.                                             TAppleEvent*     message,
  1409.                                             TAppleEvent*     reply)
  1410. {
  1411.     message->WriteType(keyAEProperty, fWhichProperty);
  1412.     return fWhichObject->HandleOSAEvent(aCommandNumber, message, reply);
  1413. }
  1414.  
  1415. #endif // qAttachable
  1416.  
  1417. //----------------------------------------------------------------------------------------
  1418. // TScriptableObjectList
  1419. //----------------------------------------------------------------------------------------
  1420. #undef Inherited
  1421. #define Inherited TList
  1422.  
  1423. #pragma segment ConstructorRes
  1424. MA_DEFINE_CLASS_M2(TScriptableObjectList, Inherited, MScriptableObject);
  1425.  
  1426. //----------------------------------------------------------------------------------------
  1427. // TScriptableObjectList::TScriptableObjectList
  1428. //----------------------------------------------------------------------------------------
  1429.  
  1430. TScriptableObjectList::TScriptableObjectList(): MScriptableObject(cScriptableObjectList)
  1431. {
  1432. }                                                // TScriptableObjectList::TScriptableObjectList
  1433.  
  1434. //----------------------------------------------------------------------------------------
  1435. // TScriptableObjectList destructor
  1436. //----------------------------------------------------------------------------------------
  1437. #pragma segment MADestructorRes
  1438.  
  1439. TScriptableObjectList::~TScriptableObjectList()
  1440. {
  1441. }
  1442.  
  1443. //----------------------------------------------------------------------------------------
  1444. // TScriptableObjectList::IScriptableObjectList
  1445. //----------------------------------------------------------------------------------------
  1446. #pragma segment MAOSLDispatch
  1447.  
  1448. void TScriptableObjectList::IScriptableObjectList(MScriptableObject* itsContainer)
  1449. {
  1450.     // Initializes the list and records the container.
  1451.     IList();
  1452.     fContainer = itsContainer;
  1453. }
  1454.  
  1455. //----------------------------------------------------------------------------------------
  1456. // TScriptableObjectList::DoAECountElements
  1457. //----------------------------------------------------------------------------------------
  1458. #pragma segment MAScriptingRes
  1459.  
  1460. void TScriptableObjectList::DoAECountElements(TAppleEvent* /*message*/,
  1461.                                          TAppleEvent* reply)
  1462. {
  1463.     // If we say "get number of (windows whose name contains "untitled")" OSL builds a
  1464.     // TAppleObjects list of TWindows that satisfies the whose test then calls this method.
  1465.     reply->WriteLong(keyAEResult, this->GetSize());
  1466. }
  1467.  
  1468. //----------------------------------------------------------------------------------------
  1469. // TScriptableObjectList::DoScriptCommand
  1470. //----------------------------------------------------------------------------------------
  1471. #pragma segment MAScriptingRes
  1472.  
  1473. void TScriptableObjectList::DoScriptCommand(CommandNumber    aCommandNumber,
  1474.                                             TAppleEvent*     message,
  1475.                                                TAppleEvent*     reply)
  1476. {
  1477.     if (aCommandNumber == cAECountElements)
  1478.         MScriptableObject::DoScriptCommand(aCommandNumber, message, reply);
  1479.     else
  1480.     {
  1481.         CTempDesc theReplyList;
  1482.         theReplyList.CreateList();
  1483.         // Calls DoScriptCommand for all the objects in the list.
  1484.         CObjectIterator iter(this);
  1485.         for (TObject * anObject = iter.FirstObject(); iter.More(); anObject = iter.NextObject())
  1486.         {
  1487.             ((MScriptableObject*)anObject)->DoScriptCommand(aCommandNumber, message, reply);
  1488.             CTempDesc theEventReply;
  1489.             if (reply->HasParameter(keyAEResult))
  1490.             {
  1491.                 reply->ReadParameter(keyAEResult, typeWildCard, theEventReply);
  1492.                 FailOSErr(AEPutDesc(theReplyList, 0, theEventReply));
  1493.             }
  1494.         }
  1495.         if (reply->fMessage.dataHandle)
  1496.             reply->WriteParameter(keyAEResult, theReplyList);
  1497.     }
  1498. }
  1499.  
  1500. //----------------------------------------------------------------------------------------
  1501. // TScriptableObjectList::InsertMarkedObject
  1502. //----------------------------------------------------------------------------------------
  1503. #pragma segment MAOSLDispatch
  1504.  
  1505. void TScriptableObjectList::InsertMarkedObject(MScriptableObject* theObjectMarked)
  1506. {
  1507.     // Adds the marked object to the list
  1508.     this->InsertLast((TObject*)theObjectMarked);
  1509. }
  1510.  
  1511. //----------------------------------------------------------------------------------------
  1512. // TScriptableObjectList::AdjustMarks
  1513. //----------------------------------------------------------------------------------------
  1514. #pragma segment MAScriptingRes
  1515.  
  1516. void TScriptableObjectList::AdjustMarks(long newStart,
  1517.                                    long newStop)
  1518. {
  1519.     // The OSL may occasionally change its mind about which objects should be marked.
  1520.     // This routine makes the adjustments.
  1521.     long numToDelete = this->GetSize() - newStop;
  1522.     if (numToDelete > 0)
  1523.         this->DeleteElementsAt(newStop + 1, numToDelete);
  1524.     numToDelete = newStart - 1;
  1525.     if (numToDelete > 0)
  1526.         this->DeleteElementsAt(1, numToDelete);
  1527. }
  1528.  
  1529. //----------------------------------------------------------------------------------------
  1530. // TScriptableObjectList::GetObjectsContainer
  1531. //----------------------------------------------------------------------------------------
  1532. #pragma segment MAOSLDispatch
  1533.  
  1534. MScriptableObject* TScriptableObjectList::GetObjectsContainer()
  1535. {
  1536.     return fContainer;
  1537. }
  1538.  
  1539. //----------------------------------------------------------------------------------------
  1540. // TScriptableObjectList::IsPropertyList
  1541. //----------------------------------------------------------------------------------------
  1542. #pragma segment MAOSLDispatch
  1543.  
  1544. Boolean TScriptableObjectList::IsPropertyList()
  1545. {
  1546.     // How do we know if this is a list of properties and not of objects?
  1547.     // We could walk down the list and make sure each element was a TPropertyAccessor,
  1548.     // but that adds overhead for large lists.
  1549.     // I haven't been able to think of a situation where objects and properties are operated
  1550.     // on at the same time and would be in the same list, so lets just check the first one.
  1551.     // I believe that even complex object specifiers can only refer to objects of the same class
  1552.     // and in the same container.
  1553.  
  1554.     TObject * theFirstObject = NULL;
  1555.     if (fSize > 0)
  1556.         theFirstObject = (TObject *)this->At(1);
  1557.     return (theFirstObject) && (((MScriptableObject*)theFirstObject)->GetOMClass() == cProperty);
  1558. }
  1559.  
  1560. //----------------------------------------------------------------------------------------
  1561. // TScriptableObjectList::GetContainedObject
  1562. //----------------------------------------------------------------------------------------
  1563. #pragma segment MAOSLDispatch
  1564.  
  1565. MScriptableObject* TScriptableObjectList::GetContainedObject(DescType desiredType,
  1566.                                               DescType selectionForm,
  1567.                                               const CAEDesc& selectionData)
  1568. {
  1569.     // This method is needed when a complex object specifier has resolved into a list of objects,
  1570.     // but then actually wants a property from each one.
  1571.     // We handle this by building up a list of contained objects from each object in this list.
  1572.  
  1573.     MAVolatileInit(TScriptableObjectList*, theNewList, new TScriptableObjectList);
  1574.     MScriptableObject * theContainer = this->GetObjectsContainer();
  1575.     theNewList->IScriptableObjectList(theContainer);
  1576.     FailInfo fi;
  1577.     Try(fi)
  1578.     {
  1579.         {
  1580.             CObjectIterator iter(this);
  1581.             for (TObject * anObject = iter.FirstObject(); iter.More(); anObject = iter.NextObject())
  1582.             {
  1583.                 MScriptableObject *theResult = ((MScriptableObject*)anObject)->GetContainedObject(desiredType, selectionForm, selectionData);
  1584.                 if (theResult == NULL)
  1585.                     FailOSErr(errAENoSuchObject);
  1586.                 theNewList->InsertLast((TObject*)theResult);
  1587.             }
  1588.             TOSADispatcher::fgDispatcher->AddTemporaryToken(theNewList);
  1589.         }
  1590.         fi.Success();
  1591.     }
  1592.     else
  1593.     {
  1594.         FreeIfObject(theNewList);
  1595.         fi.ReSignal();
  1596.     }
  1597.     return theNewList;
  1598. }
  1599.  
  1600. //----------------------------------------------------------------------------------------
  1601. // TScriptableObjectList::CountContainedObjects
  1602. //----------------------------------------------------------------------------------------
  1603. #pragma segment MAOSLDispatch
  1604.  
  1605. long TScriptableObjectList::CountContainedObjects(DescType desiredType)
  1606. // Adds up CountContainedObjects for all objects in the list.
  1607. {
  1608.     long result = 0;
  1609.     CObjectIterator iter(this);
  1610.     for (TObject * anObject = iter.FirstObject(); iter.More(); anObject = iter.NextObject())
  1611.         result += ((MScriptableObject*)anObject)->CountContainedObjects(desiredType);
  1612.     return result;
  1613. }
  1614.  
  1615. //----------------------------------------------------------------------------------------
  1616. // TSetPropertyEvent
  1617. //----------------------------------------------------------------------------------------
  1618. #undef Inherited
  1619. #define Inherited TAppleEvent
  1620.  
  1621. #pragma segment ConstructorRes
  1622. MA_DEFINE_CLASS_M1(TSetPropertyEvent, Inherited);
  1623.  
  1624. //----------------------------------------------------------------------------------------
  1625. // TSetPropertyEvent::TSetPropertyEvent
  1626. //----------------------------------------------------------------------------------------
  1627.  
  1628. TSetPropertyEvent::TSetPropertyEvent()
  1629. {
  1630. }
  1631.  
  1632. //----------------------------------------------------------------------------------------
  1633. // TSetPropertyEvent destructor
  1634. //----------------------------------------------------------------------------------------
  1635. #pragma segment MADestructorRes
  1636.  
  1637. TSetPropertyEvent::~TSetPropertyEvent()
  1638. {
  1639. }
  1640.  
  1641. //----------------------------------------------------------------------------------------
  1642. // TSetPropertyEvent::ISetPropertyEvent
  1643. //----------------------------------------------------------------------------------------
  1644. #pragma segment AEInitialize
  1645.  
  1646. void TSetPropertyEvent::ISetPropertyEvent(const CAEDesc& itsAddress,
  1647.                                           long itsSendingMode,
  1648.                                           MScriptableObject* objectToSet,
  1649.                                           DescType propType)
  1650. {
  1651.     // Initializes the event with the recipient, sending mode, the object you want to set and the 
  1652.     // property you want to modify. Creates an object specifier for the object's property and 
  1653.     // sticks it in the direct object.
  1654.     CTempDesc propertyToSet;
  1655.     CAEDesc localAddress = itsAddress;
  1656.     FailInfo fi;
  1657.     Try(fi)
  1658.     {
  1659.         this->IAppleEvent(kAECoreSuite, kAESetData, (AEAddressDesc&)localAddress, itsSendingMode);
  1660.         CAEDesc objectSpecifier;
  1661.         CAEDesc theProperty;
  1662.         objectToSet->MakeObjectSpecifier(objectSpecifier, objectToSet->GetSpecifierForm());
  1663.         theProperty.PutType(propType);
  1664.         FailOSErr(CreateObjSpecifier(cProperty, objectSpecifier, formPropertyID, theProperty, TRUE, propertyToSet));
  1665.         this->WriteParameter(keyDirectObject, propertyToSet);
  1666.         fi.Success();
  1667.     }
  1668.     else
  1669.     {
  1670.         this->Free();
  1671.         fi.ReSignal();
  1672.     }
  1673. }
  1674.  
  1675. //----------------------------------------------------------------------------------------
  1676. // TMenuAccessor
  1677. //----------------------------------------------------------------------------------------
  1678. #undef Inherited
  1679. #define Inherited TObject
  1680.  
  1681. #pragma segment ConstructorRes
  1682. MA_DEFINE_CLASS_M2(TMenuAccessor, Inherited, MScriptableObject);
  1683.  
  1684. //----------------------------------------------------------------------------------------
  1685. // TMenuAccessor::TMenuAccessor
  1686. //----------------------------------------------------------------------------------------
  1687.  
  1688. TMenuAccessor::TMenuAccessor()
  1689.     : MScriptableObject(cMenu)
  1690. {
  1691. }                                                // TMenuAccessor::TMenuAccessor
  1692.  
  1693. //----------------------------------------------------------------------------------------
  1694. // TMenuAccessor destructor
  1695. //----------------------------------------------------------------------------------------
  1696. #pragma segment MADestructorRes
  1697.  
  1698. TMenuAccessor::~TMenuAccessor()
  1699. {
  1700. }
  1701.  
  1702. //----------------------------------------------------------------------------------------
  1703. // TMenuAccessor::IMenuAccessor
  1704. //----------------------------------------------------------------------------------------
  1705. #pragma segment MAOSLDispatch
  1706.  
  1707. void TMenuAccessor::IMenuAccessor(MenuRef theMenu, short theIndex)
  1708. {
  1709.     IObject();
  1710.     fMenu = theMenu;
  1711.     fIndex = theIndex;
  1712. }
  1713.  
  1714. //----------------------------------------------------------------------------------------
  1715. // TMenuAccessor::GetObjectProperty
  1716. //----------------------------------------------------------------------------------------
  1717. #pragma segment MAOSLDispatch
  1718.  
  1719. Boolean TMenuAccessor::GetObjectProperty(CAEDesc& thePropertyValue,
  1720.                                          DescType whichProperty,
  1721.                                          const CAEDesc& desiredType)
  1722. {
  1723.     Boolean hasProperty = TRUE;
  1724.     FailInfo fi;
  1725.     Try(fi)
  1726.     {
  1727.         switch (whichProperty)
  1728.         {
  1729.     
  1730.             case pName:
  1731.                 {
  1732.                     CStr255 theMenuName = (CStr255&)(**fMenu).menuData;
  1733.                     thePropertyValue.PutString(theMenuName);
  1734.                 }
  1735.                 break;
  1736.                 
  1737.             case pIndex:
  1738.                 {
  1739.                     thePropertyValue.PutLong(fIndex);
  1740.                 }
  1741.                 break;
  1742.     
  1743.             case pMenuID:
  1744.                 {
  1745.                     thePropertyValue.PutLong((long)(**fMenu).menuID);
  1746.                 }
  1747.                 break;
  1748.     
  1749.             default:
  1750.                 hasProperty = MScriptableObject::GetObjectProperty(thePropertyValue, whichProperty, desiredType);
  1751.                 break;
  1752.         }
  1753.         fi.Success();
  1754.     }
  1755.     else
  1756.     {
  1757.         hasProperty = FALSE;
  1758.     }
  1759.     return hasProperty;
  1760. }
  1761.  
  1762. //----------------------------------------------------------------------------------------
  1763. // TMenuAccessor::SetObjectProperty: 
  1764. //----------------------------------------------------------------------------------------
  1765. #pragma segment MAScriptingRes
  1766.  
  1767. void TMenuAccessor::SetObjectProperty(const CAEDesc& thePropertyValue,
  1768.                                       DescType whichProperty)
  1769. {
  1770.     switch (whichProperty)
  1771.     {
  1772.         case pName:
  1773.         case pMenuID:
  1774.             FailOSErr(errAECantSetReadOnly);
  1775.             break;
  1776.  
  1777.         default:
  1778.             MScriptableObject::SetObjectProperty(thePropertyValue, whichProperty);
  1779.             break;
  1780.     }
  1781. }
  1782.  
  1783. //----------------------------------------------------------------------------------------
  1784. // TMenuAccessor::GetContainedObject
  1785. //----------------------------------------------------------------------------------------
  1786. #pragma segment MAOSLDispatch
  1787.  
  1788. MScriptableObject* TMenuAccessor::GetIndContainedObject(DescType desiredType,
  1789.                                                        long index)
  1790. {
  1791.     if (desiredType == cMenuItem)
  1792.     {
  1793.         // Create a menu item accessor to handle events for this menu item
  1794.         TMenuItemAccessor* theAccessor = new TMenuItemAccessor;
  1795.         theAccessor->IMenuItemAccessor(fMenu, (short)index);
  1796.         TOSADispatcher::fgDispatcher->AddTemporaryToken(theAccessor);
  1797.         return theAccessor;
  1798.     }
  1799.     else
  1800.         return MScriptableObject::GetIndContainedObject(desiredType, index);
  1801. }
  1802.  
  1803. //----------------------------------------------------------------------------------------
  1804. // TMenuAccessor::CountContainedObjects
  1805. //----------------------------------------------------------------------------------------
  1806. #pragma segment MAOSLDispatch
  1807.  
  1808. long TMenuAccessor::CountContainedObjects(DescType desiredType)
  1809.     // Returns the number of menu item in a menu.
  1810. {
  1811.     if (desiredType == cMenuItem)
  1812.         return CountMItems(fMenu);
  1813.     else
  1814.         return MScriptableObject::CountContainedObjects(desiredType);
  1815. }
  1816.  
  1817. //----------------------------------------------------------------------------------------
  1818. // TMenuItemAccessor
  1819. //----------------------------------------------------------------------------------------
  1820. #undef Inherited
  1821. #define Inherited TObject
  1822.  
  1823. #pragma segment ConstructorRes
  1824. MA_DEFINE_CLASS_M2(TMenuItemAccessor, Inherited, MScriptableObject);
  1825.  
  1826. //----------------------------------------------------------------------------------------
  1827. // TMenuItemAccessor::TMenuItemAccessor
  1828. //----------------------------------------------------------------------------------------
  1829.  
  1830. TMenuItemAccessor::TMenuItemAccessor(): MScriptableObject(cMenuItem)
  1831. {
  1832. }                                                // TMenuItemAccessor::TMenuItemAccessor
  1833.  
  1834. //----------------------------------------------------------------------------------------
  1835. // TMenuItemAccessor destructor
  1836. //----------------------------------------------------------------------------------------
  1837. #pragma segment MADestructorRes
  1838.  
  1839. TMenuItemAccessor::~TMenuItemAccessor()
  1840. {
  1841. }
  1842.  
  1843. //----------------------------------------------------------------------------------------
  1844. // TMenuItemAccessor::IMenuItemAccessor
  1845. //----------------------------------------------------------------------------------------
  1846. #pragma segment MAOSLDispatch
  1847.  
  1848. void TMenuItemAccessor::IMenuItemAccessor(MenuRef theMenu, short theItem)
  1849. {
  1850.     IObject();
  1851.     fMenu = theMenu;
  1852.     fMenuItem = theItem;
  1853. }
  1854.  
  1855. //----------------------------------------------------------------------------------------
  1856. // TMenuItemAccessor::GetObjectProperty
  1857. //----------------------------------------------------------------------------------------
  1858. #pragma segment MAOSLDispatch
  1859.  
  1860. Boolean TMenuItemAccessor::GetObjectProperty(CAEDesc& thePropertyValue,
  1861.                                              DescType whichProperty,
  1862.                                              const CAEDesc& desiredType)
  1863. {
  1864.     Boolean hasProperty = TRUE;
  1865.     FailInfo fi;
  1866.     Try(fi)
  1867.     {
  1868.         switch (whichProperty)
  1869.         {
  1870.     
  1871.             case pName:
  1872.                 {
  1873.                     CStr255 theItemName;
  1874.                     GetMenuItemText(fMenu, fMenuItem, theItemName);
  1875.                     thePropertyValue.PutString(theItemName);
  1876.                 }
  1877.                 break;
  1878.                 
  1879.             case pItemNumber:
  1880.             case pIndex:
  1881.                 {
  1882.                     thePropertyValue.PutLong(fMenuItem);
  1883.                 }
  1884.                 break;
  1885.     
  1886.             case pEnabled:
  1887.                 {
  1888.                     Boolean isEnabled = FALSE;
  1889.                     if ((fMenuItem > 0) && (fMenuItem < 32))
  1890.                         isEnabled = ((((*fMenu)->enableFlags >> fMenuItem) & 0x01) != 0);
  1891.                     else
  1892.                         isEnabled = TRUE;
  1893.                     thePropertyValue.PutBoolean(isEnabled);
  1894.                 }
  1895.                 break;
  1896.     
  1897.             default:
  1898.                 hasProperty = MScriptableObject::GetObjectProperty(thePropertyValue, whichProperty, desiredType);
  1899.                 break;
  1900.         }
  1901.         fi.Success();
  1902.     }
  1903.     else
  1904.     {
  1905.         hasProperty = FALSE;
  1906.     }
  1907.     return hasProperty;
  1908. }
  1909.  
  1910. //----------------------------------------------------------------------------------------
  1911. // TMenuItemAccessor::SetObjectProperty: 
  1912. //----------------------------------------------------------------------------------------
  1913. #pragma segment MAScriptingRes
  1914.  
  1915. void TMenuItemAccessor::SetObjectProperty(const CAEDesc& thePropertyValue,
  1916.                                       DescType whichProperty)
  1917. {
  1918.     switch (whichProperty)
  1919.     {
  1920.         case pName:
  1921.         case pItemNumber:
  1922.         case pEnabled:
  1923.             FailOSErr(errAECantSetReadOnly);
  1924.             break;
  1925.  
  1926.         default:
  1927.             MScriptableObject::SetObjectProperty(thePropertyValue, whichProperty);
  1928.             break;
  1929.     }
  1930. }
  1931.  
  1932. //----------------------------------------------------------------------------------------
  1933. // TMenuItemAccessor::DoAEOpen
  1934. //----------------------------------------------------------------------------------------
  1935. #pragma segment MAOSLDispatch
  1936.  
  1937. void TMenuItemAccessor::DoAEOpen(TAppleEvent*    /* message */ ,
  1938.                                  TAppleEvent* /* reply */)
  1939. {
  1940.     gDispatcher->MenuEvent(((long)(**fMenu).menuID << 16) | fMenuItem);
  1941. }
  1942.  
  1943. //----------------------------------------------------------------------------------------
  1944. // End of UScripting.cp
  1945.  
  1946. #pragma segment Inline
  1947.